//
//  RCAnimatedImagesView.m
//  RCloudMessage
//
//  Created by 杜立召 on 15/3/18.
//  Copyright (c) 2015年 RongCloud. All rights reserved.
//

#import "RCAnimatedImagesView.h"

#define noImageDisplayingIndex -1
#define imageSwappingAnimationDuration 2.0f

#define imageViewsBorderOffset 150

@interface RCAnimatedImagesView () {
  BOOL animating;
  NSUInteger totalImages;
  NSUInteger currentlyDisplayingImageViewIndex;
  NSInteger currentlyDisplayingImageIndex;
}

@property(nonatomic, retain) NSArray *imageViews;
@property(nonatomic, retain) NSTimer *imageSwappingTimer;

- (void)_init;

+ (NSUInteger)randomIntBetweenNumber:(NSUInteger)minNumber
                           andNumber:(NSUInteger)maxNumber;
@end

@implementation RCAnimatedImagesView

@synthesize imageViews = _imageViews;
@synthesize imageSwappingTimer = _imageSwappingTimer;

@synthesize delegate = _delegate, timePerImage = _timePerImage;

- (id)initWithCoder:(NSCoder *)aDecoder {
  if ((self = [super initWithCoder:aDecoder])) {
    [self _init];
  }

  return self;
}

- (id)initWithFrame:(CGRect)frame {
  if ((self = [super initWithFrame:frame])) {
    [self _init];
  }

  return self;
}

- (void)_init {
  NSMutableArray *imageViews = [NSMutableArray array];

  for (int i = 0; i < 2; i++) {
    UIImageView *imageView = [[UIImageView alloc]
        initWithFrame:CGRectMake(-imageViewsBorderOffset * 3.3,
                                 -imageViewsBorderOffset,
                                 self.bounds.size.width +
                                     (imageViewsBorderOffset * 2),
                                 self.bounds.size.height +
                                     (imageViewsBorderOffset * 2))];
    imageView.autoresizingMask =
        UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    imageView.contentMode = UIViewContentModeScaleAspectFill;
    imageView.clipsToBounds = NO;
    [self addSubview:imageView];

    [imageViews addObject:imageView];
  }

  self.imageViews = [imageViews copy];

  currentlyDisplayingImageIndex = noImageDisplayingIndex;
}

- (void)startAnimating {

  if (!animating) {
    animating = YES;
    [self.imageSwappingTimer fire];
  }
}

- (void)bringNextImage {

  UIImageView *imageViewToHide =
      [self.imageViews objectAtIndex:currentlyDisplayingImageViewIndex];

  currentlyDisplayingImageViewIndex =
      currentlyDisplayingImageViewIndex == 0 ? 1 : 0;

  UIImageView *imageViewToShow =
      [self.imageViews objectAtIndex:currentlyDisplayingImageViewIndex];

  NSUInteger nextImageToShowIndex = 0;

  do {
    nextImageToShowIndex =
        [[self class] randomIntBetweenNumber:0 andNumber:totalImages - 1];
  } while (nextImageToShowIndex == currentlyDisplayingImageIndex);

  currentlyDisplayingImageIndex = nextImageToShowIndex;

  imageViewToShow.image =
      [self.delegate animatedImagesView:self imageAtIndex:nextImageToShowIndex];

  static const CGFloat kMovementAndTransitionTimeOffset = 0.1;

  [UIView
      animateWithDuration:self.timePerImage + imageSwappingAnimationDuration +
                          kMovementAndTransitionTimeOffset
                    delay:0.0
                  options:UIViewAnimationOptionBeginFromCurrentState |
                          UIViewAnimationCurveLinear
               animations:^{
                 NSInteger randomTranslationValueX =
                     imageViewsBorderOffset * 3.5 -
                     [[self class]
                         randomIntBetweenNumber:0
                                      andNumber:imageViewsBorderOffset];
                 NSInteger randomTranslationValueY = 0;

                 CGAffineTransform translationTransform =
                     CGAffineTransformMakeTranslation(randomTranslationValueX,
                                                      randomTranslationValueY);

                 CGFloat randomScaleTransformValue =
                     [[self class] randomIntBetweenNumber:115 andNumber:120] /
                     100;

                 CGAffineTransform scaleTransform = CGAffineTransformMakeScale(
                     randomScaleTransformValue, randomScaleTransformValue);

                 imageViewToShow.transform = CGAffineTransformConcat(
                     scaleTransform, translationTransform);
               }
               completion:NULL];

  [UIView animateWithDuration:imageSwappingAnimationDuration
      delay:kMovementAndTransitionTimeOffset
      options:UIViewAnimationOptionBeginFromCurrentState |
              UIViewAnimationCurveLinear
      animations:^{
        imageViewToShow.alpha = 1.0;
        imageViewToHide.alpha = 0.0;
      }
      completion:^(BOOL finished) {
        if (finished) {
          imageViewToHide.transform = CGAffineTransformIdentity;
        }
      }];
}

- (void)reloadData {
  totalImages = [self.delegate animatedImagesNumberOfImages:self];

  [self.imageSwappingTimer fire];
}

- (void)stopAnimating {
  if (animating) {
    [_imageSwappingTimer invalidate];
    _imageSwappingTimer = nil;

    [UIView animateWithDuration:imageSwappingAnimationDuration
        delay:0.0
        options:UIViewAnimationOptionBeginFromCurrentState
        animations:^{
          for (UIImageView *imageView in self.imageViews) {
            imageView.alpha = 0.0;
          }
        }
        completion:^(BOOL finished) {
          currentlyDisplayingImageIndex = noImageDisplayingIndex;
          animating = NO;
        }];
  }
}

- (NSTimeInterval)timePerImage {
  if (_timePerImage == 0) {
    return kJSAnimatedImagesViewDefaultTimePerImage;
  }

  return _timePerImage;
}

- (void)setDelegate:(id<RCAnimatedImagesViewDelegate>)delegate {
  if (delegate != _delegate) {
    _delegate = delegate;
    totalImages = [_delegate animatedImagesNumberOfImages:self];
  }
}

- (NSTimer *)imageSwappingTimer {
  if (!_imageSwappingTimer) {
    _imageSwappingTimer =
        [NSTimer scheduledTimerWithTimeInterval:self.timePerImage
                                         target:self
                                       selector:@selector(bringNextImage)
                                       userInfo:nil
                                        repeats:YES];
  }

  return _imageSwappingTimer;
}

+ (NSUInteger)randomIntBetweenNumber:(NSUInteger)minNumber
                           andNumber:(NSUInteger)maxNumber {
  if (minNumber > maxNumber) {
    return [self randomIntBetweenNumber:maxNumber andNumber:minNumber];
  }

  NSUInteger i = (arc4random() % (maxNumber - minNumber + 1)) + minNumber;

  return i;
}

#pragma mark - Memory Management

- (void)dealloc {
  [_imageSwappingTimer invalidate];
}

@end
